package containerModel

import (
	sqlmodel "cmdb-go/commonorm"
	"cmdb-go/configmodel"
	"cmdb-go/shellmodel"
	"cmdb-go/structmodel"
	wechatmodel "cmdb-go/wechatmsgmodel"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)


func ContainerDelete(containerNode,containerId string) {
	/*
		传递docker remote api 以停止正在运行的容器 并删除它
	*/
	ids := strings.TrimRight(containerId,"\n")
	deleteContainerUrl := fmt.Sprintf("http://%s:2375/containers/%s",containerNode,ids)
	stopContainerUrl := fmt.Sprintf("http://%s:2375/containers/%s/stop",containerNode,ids)
	stopContainer,_ := http.NewRequest("POST",stopContainerUrl,nil)
	deleteContainer,_ := http.NewRequest("DELETE",deleteContainerUrl,nil)
	stopRes,stopErr := http.DefaultClient.Do(stopContainer)
	deleteRes,deleErr := http.DefaultClient.Do(deleteContainer)
	fmt.Println(stopErr,deleErr)
	if stopErr != nil {
		fmt.Println("停止错误：",stopErr)
		return
	}
	if deleErr != nil {
		fmt.Println("删除错误：",deleErr)
		return
	}
	fmt.Println(stopRes,deleteRes)
}

func ContainerCheck() (resmap map[string]map[string]interface{}) {
	/*
	   在sqlmodel中已经写有获取所有容器信息并返回的sql函数 直接引用即可 返回的数据只需断言即可使用
	*/
	AllcontainerinfoGet := sqlmodel.SqlGet().([]structmodel.ContainerInfo)
	var AllNodecontainerlist []structmodel.Docker
	resMap := make(map[string]map[string]interface{})
	nodes := configmodel.ConfigGet().ContainerNodes
	for _,nodeIp := range nodes {
		NodesContainerinfo := fmt.Sprintf("http://%s:2375/containers/json?all=1",nodeIp)
		nodecontainerinfoget,_ := http.NewRequest("GET",NodesContainerinfo,nil)
		nodecontainerinfores,_ := http.DefaultClient.Do(nodecontainerinfoget)
		nodecontainerinfoRes,_ := ioutil.ReadAll(nodecontainerinfores.Body)
		_ = json.Unmarshal(nodecontainerinfoRes, &AllNodecontainerlist)
		for _,v := range AllNodecontainerlist {
			for _,c := range AllcontainerinfoGet {
				if c.ContainerName == strings.Trim(v.Names[0],"/") {
					//fmt.Println(v.Status,"--------------",c.ContainerName,"-------------",c.ContainerNode,c.RunUser,c.UpdatedAt)
					if strings.Contains(v.Status, "Exited") {
						infoMap := make(map[string]interface{})
						//fmt.Println(v.Status,"--------------",c.ContainerName,"-------------",c.ContainerNode,c.RunUser)
						infoMap["status"] = false
						infoMap["node"] = c.ContainerNode
						infoMap["user"] = c.RunUser
						resMap[c.ContainerName] = infoMap
					}
				}
			}
		}
	}
	fmt.Println("返回的数据是",resMap)
	return resMap
}

func CronContainerClaer()  {
	timeinterval := configmodel.ConfigGet().TimeInterval
	fmt.Println(timeinterval)
	AllcontainerinfoGet := sqlmodel.SqlGet().([]structmodel.ContainerInfo)
	fmt.Println("开始检查",len(AllcontainerinfoGet),"条容器数据")
	for _, infos:= range AllcontainerinfoGet {
		if ((time.Now().Unix() - infos.UpdatedAt.Unix()) / 60) > timeinterval {
			err := shellmodel.OrangeUpsModify(infos.ContainerEnv,infos.ContainerTag,infos.ContainerProject,infos.RunUser)
			if err != nil {
				fmt.Println("orange配置文件修改失败",err)
			}
			sqlmodel.SqlDelete(infos.ContainerName)
			fmt.Println("容器时间到期清理：",infos.ContainerName,infos.ContainerNode,infos.ContainerIds)
			ContainerDelete(infos.ContainerNode,infos.ContainerIds)
		} else {
			fmt.Println(infos.ContainerName,infos.ContainerNode,strings.TrimRight(infos.ContainerIds,"\n"),"容器时间未到期")
		}
	}
	fmt.Println("检查结束",len(AllcontainerinfoGet),"条容器数据")
}

var monitTmp = make(map[string]map[string]string)
func CheckContainerjob (){
	checkResListMap := ContainerCheck()
	for k,info := range monitTmp {
		v,ok := checkResListMap[k]
		if ok {
			fmt.Println(v,"++++++++++++++++++++++++++++> 容器异常状态已搜集")
		} else {
			fmt.Println(k,"容器已恢复 正在修改数据库状态")
			wechatmodel.RecoverMessage(info["user"],k,info["node"])
			fmt.Println("恢复报警",info["user"],k,info["node"])
			delete(monitTmp, k)
			sqlmodel.ContainerStatusMonitor(k, true)
		}
	}
	if len(checkResListMap) != 0 {
		fmt.Println(checkResListMap)
		for name,infos := range checkResListMap {
			v,ok := monitTmp[name]
			if ok {
				fmt.Println(v,"----------------------------> 容器异常状态已报警并缓存")
			} else {
				user := infos["user"].(string)
				node := infos["node"].(string)
				wechatmodel.AlertMessage(user,name,node)
				fmt.Println("异常报警",user,name,node)
				fmt.Println(name,"容器异常 正在添加至数据库")
				containerstatus := infos["status"].(bool)
				sqlmodel.ContainerStatusMonitor(name, containerstatus)
				infoTmp := make(map[string]string)
				infoTmp["user"] = user
				infoTmp["node"] = node
				monitTmp[name] = infoTmp
			}
		}
	} else {
		fmt.Println("容器节点 容器运行无异常")
	}
	fmt.Println("已报警缓存---------------------------------->",monitTmp)
}
